#include "AssetManager.h"

AssetManager::AssetManager() {
	RE_Logger::GetGlobalLogger()->WriteLog("Initializing the asset manager.");
	RE_Logger::GetGlobalLogger()->WriteLog("Importing the standart asset parsers");
	//add here standart parsers.
	std::string fmt = ".ase";
	AddParser(fmt,AssetParserPtr(RE_NEW ASEParser)); 
	fmt = ".fx";
	AddParser(fmt,AssetParserPtr(RE_NEW EffectCreator));
	fmt = ".jpg";
	AssetParserPtr textureCreator(RE_NEW TextureCreator);
	AddParser(fmt, textureCreator);
	fmt = ".png";
	AddParser(fmt, textureCreator);
	fmt = ".rel";
	AddParser(fmt, AssetParserPtr(RE_NEW RELevelParser));
}
AssetManager::~AssetManager() {
	m_ParserMap.clear(); // clears all parsers
	ResourceMap::iterator i = m_ResourceMap.begin();
	while(i != m_ResourceMap.end())
	{
		AssetDataList::iterator u = i->second.begin();
		while(u != i->second.end())
		{
			(*u)->RemoveChildren();
			++u;
		}
		++i;
	}
	m_ResourceMap.clear();
	m_AssetNameMap.clear();
}
AssetDataPtr AssetManager::GetAssetData(const std::string & node_name)
{
	return GetAssetData(RE_String(node_name));
}
AssetDataPtr AssetManager::GetAssetData(const RE_String & node_name)
{
	AssetNameMap::iterator i = m_AssetNameMap.find(node_name);
	if(i == m_AssetNameMap.end())
	{
		return AssetDataPtr();
	}
	return (*i).second;
}
AssetDataList * AssetManager::GetAssetData(Resource &res)
{
	AssetDataList * asset = FindAssets(res);
	if(asset != NULL)
	{
		return asset;
	}else
	{
		return LoadAssets(res);
	}
}

AssetDataList * AssetManager::FindAssets(Resource &res)
{
	ResourceMap::iterator i = m_ResourceMap.find(res);
	if(i != m_ResourceMap.end())
	{
		return &i->second;
	}
	return NULL;
}

bool AssetManager::RemoveAssets(Resource &res)
{
	ResourceMap::iterator i = m_ResourceMap.find(res);
	AssetDataList::iterator u = (*i).second.begin();
	while(u != (*i).second.end())
	{
		AssetNameMap::iterator y = m_AssetNameMap.find((*u)->GetName());
		if(y != m_AssetNameMap.end())
		{
			m_AssetNameMap.erase(y);
		}
		++u;
	}
	if(i != m_ResourceMap.end())
	{
		m_ResourceMap.erase(res);
		return true;
	}
	return false;
}


AssetDataList * AssetManager::LoadAssets(RE::IO::FilePath &res)
{
	ParserMap::iterator i = m_ParserMap.find(res.GetFileName());
	if( i == m_ParserMap.end())
	{
		assert(0 && "Somethign went wrong!");
		return NULL;
	}
	ResHandlePtr handle = REC()->VGetHandle(res);
	AssetDataList * assets = &i->second->VLoad(res, handle->VGetBuffer(), handle->VGetSize());
	AddAsset(res, assets);
	return assets;
}


void AssetManager::AddParser(std::string & format, AssetParserPtr ptr)
{
	//for now only one parser for format
	ParserMap::iterator i = m_ParserMap.find(format);
	if( i != m_ParserMap.end())
	{
		assert(0 && "Somethign went wrong!");
		return;
	}
	m_ParserMap[format] = ptr;
}
void AssetManager::AddAsset(RE::IO::FilePath & res, AssetDataList * assets)
{
	m_ResourceMap[res] = *assets;
	AssetDataList::iterator i = assets->begin();
	while(i != assets->end())
	{
		m_AssetNameMap.insert(std::make_pair<RE_String, AssetDataPtr>((*i)->GetName(), (*i)));
		++i;
	}
}
void AssetManager::RestoreAssets()
{
	AssetNameMap::iterator i = m_AssetNameMap.begin();
	while(i != m_AssetNameMap.end())
	{
		(*i).second->Restore();
		(*i).second->RestoreChildren();
		++i;
	}
}
void AssetManager::ReleaseAssets(const bool OnlyBuffers)
{
	if(OnlyBuffers)
	{
		AssetNameMap::iterator i = m_AssetNameMap.begin();
		while(i != m_AssetNameMap.end())
		{
			(*i).second->Release();
			++i;
		}
	}
	else
	{
		m_AssetNameMap.clear();
		m_ResourceMap.clear();
		//Release Parsers also
		m_ParserMap.clear();
	}
}
void AssetManager::RemoveParser(AssetParserPtr)
{
}
void AssetManager::RemoveParser(std::string & format)
{
}